<?php

namespace app\admin\command;

use app\admin\command\Api\library\Builder;
use app\admin\model\AdminSalaryBenchmarkItem;
use app\admin\model\ClassHour;
use app\admin\model\SalaryBenchmark;
use app\admin\model\SalaryBenchmarkData;
use app\admin\model\SalaryCalculationTemplateItem;
use app\admin\model\WorkTemplateLog;
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Exception;

class Plan extends Command
{
    protected function configure()
    {
        $site = Config::get('site');
        $this->setName('plan')->setDescription('计划任务');
    }

    protected function execute(Input $input, Output $output)
    {
        // 计算工资预警
        $this->salary_warning($input,$output);

        // 计算工资
        $this->salary_wages($input,$output);
    }

    // 计算工资
    public function salary_wages(Input $input, Output $output){
        $output->info('计算工资');
        $list = Db::table('b_salary')->where('status',0)->select();
        foreach ($list as $item){ // 循环计算
            $output->info($item['name'].' 计算中...');
            $template_item_arr = collection(SalaryCalculationTemplateItem::where('template_id',$item['template_id'])->select())->toArray();
            $item['start_time'] = date('Y-m-d',strtotime($item['start_time']));
            $item['end_time'] = date('Y-m-d',strtotime($item['end_time']));
            for($i=0;$i<=0;$i--){
                Db::startTrans();
                $info = Db::table('b_salary_item')->where('salary_id',$item['id'])->where('result',0)->find();
                if(empty($info)){
                    $i = 5;
                }else{
                    Db::table('b_salary_item')->where('id',$info['id'])->update([
                        'result' => 1,
                    ]);
                    $admin = Db::table('b_admin')->field('nickname,lesson_count')->where('id',$info['admin_id'])->find();
                    $nickname = $admin['nickname'];
                    $lesson_count = $admin['lesson_count'];
                    $content_arr = [
                        [
                            'name'=>"姓名",
                            'item_type' => 5,
                            'money'=>$nickname,
                        ]
                    ];
                    //合计金额
                    $total_money = 0;
                    $error = 0;
                    foreach ($template_item_arr as $v){
                        if($error != 1){
                            $money_res = $this->_get_money( $v['formula'],$info['admin_id'],$item['start_time'].'00:00:00',$item['end_time'].'23:59:59',$lesson_count);
                            if($money_res['code'] != 1){
                                Db::table('b_salary_item')->where('id',$info['id'])->update([
                                    'result' => 3
                                ]);
                                $error = 1;
                            }
                            array_push($content_arr,array(
                                'name' => $v['item_name'],
                                'item_type' => $v['item_type'],
                                'money' => $money_res['data']
                            ));
                            if($v['item_type'] == 1){
                                $total_money -= $money_res['data'];
                            }else if ($v['item_type'] == 3){

                            }else{
                                $total_money += $money_res['data'];
                            }
                        }
                    }
                    array_push($content_arr,array(
                        'name'=>"合计",
                        'item_type' => $total_money > 0 ? 2 : 1,
                        'money'=>$total_money,
                    ));

                    if($error == 0){
                        Db::table('b_salary_item')->where('id',$info['id'])->update([
                            'result' => 2,
                            'content' => json_encode($content_arr)
                        ]);
                    }
                    $output->info('计算完成：'.$nickname);
                }
                Db::commit();
            }

            if(!Db::table('b_salary_item')->where('salary_id',$item['id'])->whereIn('result',[0,1])->count()){
                Db::table('b_salary')->where('id',$item['id'])->update([
                    'status' => 1,
                ]);
            }
        }
    }

    // 计算工资预警
    public function salary_warning(Input $input, Output $output){
        $output->info('计算工资预警');
        $time = date('Y-m-d').' 00:00:00';
        for($i=5;$i>=0;$i--){
            $year = date('Y') - $i;
            $list = Db::table('b_basis_wages_capping')
                ->where(function ($query) use ($time,$year){
                    $query->where(function($q) use ($time,$year){
                        $q->where([
                            'year' => $year,
                            'update_time' => ['lt',$time]
                        ]);
                    })->whereOr('recalculate',1);
                })
                ->select();
            foreach ($list as $val){
                $update_data = [
                    'update_time' => current_time(),
                    'recalculate' => 0,
                ];
                //   计算工资
                $salary_ids = Db::table('b_salary')->where('start_time','like',"%{$year}%")->column('id');

                if($salary_ids){
                    $all_price = 0;
                    $item_List = Db::table('b_salary_item')->whereIn('salary_id',$salary_ids)->select();
                    foreach ($item_List as $item){
                        $content = json_decode($item['content'],1);
                        foreach ($content as $v){
                            if($v['name'] == '合计'){
                                $all_price = $all_price + $v['money'];
                            }
                        }
                    }
                    $update_data['price'] = $all_price;
                    $update_data['proportion'] = number_format($all_price/$val['early_warning'],4) * 100;
                }
                Db::table('b_basis_wages_capping')->where('id',$val['id'])->update($update_data);
            }
            $output->info($year.'年计算完成');
        }


    }




    public function _get_money($formula,$admin_id,$start_time,$end_time,$lesson_count = 1)
    {
        try{
            $formula = json_decode($formula,true);
            $new_formula = '';
            foreach ($formula as $item) {
                if ($item['type'] == '2' || $item['type'] == '3') { // 2 计算公式 3 自定义数值
                    $new_formula .= $item['value'];
                } elseif ($item['type'] == '1') {  // 1:选择的计算项
                    $value_arr = explode('-',$item['value']);
                    if(empty($value_arr))exception('计算公式格式错误');
                    if($value_arr[0] == 999){ // 新加内容
                        switch ($value_arr[1]) {
                            case 1:  // 值白班
                                $single_price = $this->single_price(3);
                                // 计算次数
                                $number = calculate_count(1,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 2:  // 值夜班
                                $single_price = $this->single_price(4);
                                // 计算次数
                                $number = calculate_count(2,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 3:  // 值夜宿班
                                $single_price = $this->single_price(5);
                                // 计算次数
                                $number = calculate_count(3,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 4:  // 社团费用
                                $z_single_price = $this->single_price(16);
                                // 计算次数
                                $z_number = calculate_count(8,$admin_id,$start_time,$end_time);

                                $h_single_price = $this->single_price(17);
                                // 计算次数
                                $h_number = calculate_count(9,$admin_id,$start_time,$end_time);
                                $value = $z_single_price * $z_number + $h_single_price * $h_number;
                                break;
                            case 5:  // 课业辅导费用
                                $single_price = $this->single_price(7);
                                // 计算次数
                                $number = calculate_count(5,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 6:  // 护导费用
                                $single_price = $this->single_price(8);
                                // 计算次数
                                $number = calculate_count(6,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 7:  // 代班主任费用
                                $single_price = $this->single_price(9);
                                $number = simple_count(7,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 8:  // 被代班主任费用
                                $single_price = $this->single_price(9);
                                $number = simple_count(8,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 11:  // 主科-课时费用
                                if($lesson_count == 0){
                                    $value = 0;
                                }else{
                                    $single_price = $this->single_price(12);
                                    $number = subject_calculate(11,$admin_id,$start_time,$end_time);
                                    $value = $single_price * $number;
                                }
                                break;
                            case 12:  // 主科-代课费用
                                $single_price = $this->single_price(10);
                                $number = subject_calculate(12,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 13:  // 主科-被代课费用
                                $single_price = $this->single_price(10);
                                $number = subject_calculate(13,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 14:  // 科任-课时费用
                                if($lesson_count == 0){
                                    $value = 0;
                                }else{
                                    $single_price = $this->single_price(13);
                                    $number = subject_calculate(14,$admin_id,$start_time,$end_time);
                                    $value = $single_price * $number;
                                }
                                break;
                            case 15:  // 科任-代课费用
                                $single_price = $this->single_price(11);
                                $number = subject_calculate(15,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 16:  // 科任-被代课费用
                                $single_price = $this->single_price(11);
                                $number = subject_calculate(16,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 17:  // 班队会-课时费用

                                if($lesson_count == 0){
                                    $value = 0;
                                }else{
                                    $single_price = $this->single_price(14);
                                    $number = subject_calculate(17,$admin_id,$start_time,$end_time);
                                    $value = $single_price * $number;
                                }
                                break;
                            case 18:  // 班队会-代课费用
                                $single_price = $this->single_price(15);
                                $number = subject_calculate(18,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            case 19:  // 班队会-被代课费用
                                $single_price = $this->single_price(15);
                                $number = subject_calculate(19,$admin_id,$start_time,$end_time);
                                $value = $single_price * $number;
                                break;
                            default:
                                $value = 0;
                                break;
                        }

                    }else{
                        switch ($value_arr[1]){
                            case 1:  // 计算项
                                $salary_benchmark_info = SalaryBenchmark::where('id',$value_arr[0])->find();
                                if(empty($salary_benchmark_info))exception('自定义基准项未找到');
                                if($salary_benchmark_info['count_type'] == 1){ // 次数
                                    $num = SalaryBenchmarkData::where([
                                        'status'=>4,
                                        'salary_benchmark_id'=>$salary_benchmark_info['id'],
                                        'admin_id'=>$admin_id
                                    ])
                                        ->whereTime('select_time', 'between', [$start_time, $end_time])
                                        ->sum('num');
                                    $value = $salary_benchmark_info['num_price']*$num;
                                }else{
                                    $value = AdminSalaryBenchmarkItem::with('item')
                                        ->where(['admin_salary_benchmark_item.salary_benchmark_id'=>$salary_benchmark_info['id'],'admin_id'=>$admin_id])
                                        ->sum('item.price');
                                    if(!$value){
                                        // 查分组
                                        $group_ids = Db::table('b_admin_group_access')->where('uid',$admin_id)->column('group_id');
                                        $asbi_template_arr =  Db::table('b_admin_group_asbi')->whereIn('group_id',$group_ids)->column('asbi_template_id');;
                                        $value = Db::table('b_auth_asbi_template_item a')
                                            ->join('salary_benchmark_item b','a.salary_benchmark_item_id=b.id')
                                            ->whereIn('template_id',$asbi_template_arr)
                                            ->where('a.salary_benchmark_id',$salary_benchmark_info['id'])
                                            ->sum('b.price');
                                    }
                                }
                                break;
                            case 2:  // 日常课程
                                $value = ClassHour::where(['type'=>1,'status'=>5,'admin_id'=>$admin_id,'course_type_id'=>$value_arr[0]])
                                    ->whereTime('select_time', 'between', [$start_time, $end_time])
                                    ->sum('num');
                                break;
                            case 3:  // //代课
                                $value = ClassHour::where(['type'=>2,'status'=>5,'substitute_admin_id'=>$admin_id,'course_type_id'=>$value_arr[0]])
                                    ->whereTime('select_time', 'between', [$start_time, $end_time])
                                    ->sum('num');
                                break;
                            case 4:  // 浮动性工资
                                $where = [];
                                if($value_arr[0] == 3)$where['teacher_type'] = 1;
                                $value = WorkTemplateLog::where(['type'=>$value_arr[0],'status'=>5,'admin_id'=>$admin_id])->where($where)
                                    ->whereTime('select_time', 'between', [$start_time, $end_time])
                                    ->count();
                                if($value_arr[0] == 1){ // 1 分餐
                                    $single_price = $this->single_price(1);
                                }else if($value_arr[0] == 2){ // 看班
                                    $single_price = $this->single_price(2);
                                }else { // 看班
                                    $single_price = 0;
                                }
                                $value = $value * $single_price;
                                break;
                            case 5:  // 浮动性工资助教
                                $value = WorkTemplateLog::where(['type'=>$value_arr[0],'status'=>5,'admin_id'=>$admin_id,'teacher_type'=>2])
                                    ->whereTime('select_time', 'between', [$start_time, $end_time])
                                    ->count();
                                break;
                            default:
                                $value = 0;
                                break;
                        }
                    }
                    $new_formula .= $value;

                }
            }
            $money = 0;
            eval('$money = ' . $new_formula . ';');
            return array('code'=>1,'msg'=>'ok','data'=>$money);
        }catch (\Throwable $e){
            return array('code'=>0,'msg'=>$e->getMessage());
        }

    }


    // 计算单次价格
    public function single_price($id){
        return Db::table('b_basis_cost')->where('id',$id)->value('price');
    }
}
